package hammersmith.local.valueobjects;

import hammersmith.local.exceptions.ArticleNotFoundException;
import hammersmith.local.exceptions.EmptyCartException;
import hammersmith.local.exceptions.StockTooLowException;
import hammersmith.local.exceptions.WrongMinCountException;

import java.io.Serializable;
import java.util.Hashtable;

public class ShoppingCart implements Serializable {

	private static final long serialVersionUID = -5772606545307400243L;

	Hashtable<Article, Integer> list = new Hashtable<Article, Integer>();

	public ShoppingCart() {

	}

	public Hashtable<Article, Integer> getList() {
		return list;
	}

	public void setList(Hashtable<Article, Integer> list) {
		this.list = list;
	}

	public boolean putArticleInCart(Article article, Customer customer,
			int count) throws StockTooLowException, WrongMinCountException {

		if (article instanceof MassArticle) {
			MassArticle a = (MassArticle) article;

			if (count % a.getMinCount() != 0) {
				throw new WrongMinCountException(a.getMinCount());
			}
		}

		int oldCount = 0;
		boolean ok = contains(article);

		if (ok) {
			oldCount = customer.getCart().getList().get(article).intValue();
		}

		// Nur in den Warenkorb legen, wenn der Bestand mehr oder genausoviel
		// wie der Kaufwunsch ist
		if (article.getStock() >= count + oldCount) {
			customer.getCart().getList().put(article, oldCount + count);
			return true;
		} else {
			throw new StockTooLowException();
		}
	}

	public boolean removeArticleFromCart(Article article)
			throws EmptyCartException {
		if (!this.isFilled()) {
			throw new EmptyCartException();
		}
		this.list.remove(article);
		return true;
	}

	public boolean contains(Article a) {

		// Durchlaufen des Warenkorbs...
		for (Article article : this.list.keySet()) {
			if (a == article) {
				return true;
			}
		}
		return false;
	}

	public boolean isFilled() {
		if (this.list.isEmpty()) {
			return false;
		} else {
			return true;
		}
	}

	public boolean editStock(Article a, int count)
			throws WrongMinCountException, ArticleNotFoundException,
			StockTooLowException {

		if (a instanceof MassArticle) {
			MassArticle ma = (MassArticle) a;

			if (count % ma.getMinCount() != 0) {
				throw new WrongMinCountException(ma.getMinCount());
			}
		}

		Article found = null;
		for (Article article : this.list.keySet()) {
			if (article.getId() == a.getId()) {
				found = article;
				break;
			}
		}
		int currentCount = this.list.get(found).intValue();

		// Sind soviele Artikel überhaupt da?
		if (found != null) {

			int articleStock = found.getStock();

			if (articleStock >= count) {
				
				currentCount = count;
				this.list.put(found, currentCount);
				return true;
			} else {
				throw new StockTooLowException();
			}
		}
		return false;
	}

	/**
	 * 
	 * Methode um den aktuellen Gesamtpreis des Warenkorbs zu ermitteln
	 * 
	 * @return
	 */
	public double getShoppingCartFullCosts() {
		double summe = 0;
		for (Article a : this.list.keySet()) {
			summe += a.getPrice() * this.list.get(a).doubleValue();
		}

		// Ergebnis auf 2 Kommastellen runden
		summe = summe * 100;
		summe = Math.round(summe);
		summe = summe / 100;

		return summe;
	}
	
	public void clearCart(){
		for (Article a : this.list.keySet()) {
			this.list.remove(a);
		}
	}

}
